home *** CD-ROM | disk | FTP | other *** search
- #include <dos.h>
- #include <math.h>
- #include <malloc.h>
- #include <wgt5.h>
- #include <wgtvesa.h>
- #include "wrend.h"
-
- #define PHONG 8
- #define PHONG_TEXTURE 9
- #define TRANSLUCENT_PHONG 10
-
- int rendermethod;
- int motion_blur;
- float percent_foreground;
- float percent_background;
- float motion_blur_factor;
- block virt; /* Drawing buffer */
- color pal[256]; /* A palette */
-
- /* For shaded texture mapping */
- #define NUMSHADES 64 /* Number of shades in the shade table */
- block shadetable; /* allocated dynamically, has a size
- of (NUMSHADES+1) * 256 bytes */
-
- block translucent_table; /* allocated dynamically, has a size
- of 256 * 256 bytes */
-
- float scale = 1; /* Scale used for mapping a texture onto
- a plane */
-
- float movectr = 5; /* Movement speed for camera, rotation... */
-
- #define POINTBUF 10000
- vertex vertices[POINTBUF]; /* Vertex list for world */
-
- short vmodes[6] = { V640x350, V640x400, V640x480, V800x600, V1024x768 };
-
-
- void set_initial_palette (void)
- {
- int i, c, r, g, b;
- double u;
-
- // Phong material properties
- #define SHINE 80.0
- #define SPEC 0.70
- #define PI 3.141516
- #define R0 63
- #define G0 18
- #define B0 15
-
-
- /* Phong Palette */
- if ((rendermethod == PHONG) || (rendermethod == TRANSLUCENT_PHONG))
- {
- for (i = 0; i < 256; i++)
- {
- u = SPEC*63.0*exp(SHINE*log(sin(0.5*PI*i/256.0)+0.001));
- if ((r = (i*R0/256) + u) > 63) r = 63;
- if ((g = (i*G0/256) + u) > 63) g = 63;
- if ((b = (i*B0/256) + u) > 63) b = 63;
-
- wsetrgb (i, r, g, b, pal);
- }
-
- }
- else
- {
- /* Set up some initial color ranges */
- for (i = 0; i < 64; i++)
- {
- pal[i].r = i;
- pal[i].g = i;
- pal[i].b = 0;
- }
- for (i = 64; i < 128; i++)
- {
- pal[i].r = i - 64;
- pal[i].g = 0;
- pal[i].b = 0;
- }
-
- for (i = 128; i < 192; i++)
- {
- pal[i].r = i - 128;
- pal[i].g = 0;
- pal[i].b = i - 128;
- }
- for (i = 192; i < 256; i++)
- {
- pal[i].r = 0;
- pal[i].g = 0;
- pal[i].b = i - 192;
- }
- }
-
- wsetrgb (0, 0, 0, 0, pal);
- wsetpalette (0, 255, pal);
- }
-
-
- void save_table (char *filename, block table, long size)
- {
- FILE *out;
- int i;
-
- out = fopen (filename, "wb");
- fwrite (table, size, 1, out);
- fclose (out);
- }
-
-
- block load_table (char *filename, long size)
- {
- FILE *in;
- int i;
- block table;
-
- in = fopen (filename, "rb");
- if (in != NULL)
- {
- table = (unsigned char *)malloc (size);
- fread (table, size, 1, in);
- fclose (in);
- return table;
- }
- else
- return NULL;
- }
-
-
-
-
- void load_ptext (int num)
- {
- FILE *in;
- int i;
-
- in = fopen ("face.txt", "rb");
-
- fread (ptext, sizeof(polytexture), num, in);
- fclose (in);
- }
-
-
- void save_ptext (int num)
- {
- FILE *out;
- int i;
-
- out = fopen ("face.txt", "wb");
- fwrite (ptext, sizeof (polytexture), num, out);
- fclose (out);
- }
-
-
-
-
-
-
- /* Shade Table Calculations */
- void wcreateshade (short shade, short maxshade, unsigned char *shadetable,
- color *palette)
- /* Calculate a single palette (256) colors for the given shade */
- {
- float lightlevel;
- float fr, fg, fb;
- long ir, ig, ib;
-
- long absr, absg, absb;
-
-
- double u;
- int r,g,b;
-
- short col;
- short findcol;
-
- unsigned long lowest;
- unsigned char bestfit;
- unsigned long coldif;
-
-
- lightlevel = (float)shade / maxshade;
- lightlevel += 0.2;
- if (lightlevel > 1)
- lightlevel = 1;
-
- for (col = 0; col < 256; col++)
- {
- fr = (float)palette[col].r * (lightlevel);
- fg = (float)palette[col].g * (lightlevel);
- fb = (float)palette[col].b * (lightlevel);
-
- /* Phong shade table */
- if (rendermethod == PHONG_TEXTURE)
- {
- u = SPEC*63.0*exp(SHINE*log(sin(0.5*PI*shade/maxshade)+0.001));
- if ((fr = (fr + u)) > 63) fr = 63;
- if ((fg = (fg + u)) > 63) fg = 63;
- if ((fb = (fb + u)) > 63) fb = 63;
- }
-
- ir = fr;
- ig = fg;
- ib = fb;
-
- lowest = 655350;
- for (findcol = 0; findcol < 256; findcol++)
- {
- absr = abs ( (long)palette[findcol].r - ir);
- absg = abs ( (long)palette[findcol].g - ig);
- absb = abs ( (long)palette[findcol].b - ib);
-
- //coldif = absr*absr*30 + absg*absg*59 + absb*absb*11;
- coldif = absr*absr + absg*absg + absb*absb;
- coldif = sqrt (coldif);
- if (coldif < lowest)
- {
- lowest = coldif;
- bestfit = findcol;
- }
- }
- shadetable[shade*256 + col] = bestfit;
- }
-
- }
-
-
- block wcreate_shade_table (short numshades, color *palette)
- /* Create a shade table for shaded texture mapping, with darker colors
- towards black. */
- {
- short i;
- block table;
-
- table = (unsigned char *)malloc ( (NUMSHADES+1)*256L);
-
- wtextcolor (128);
- wtexttransparent (TEXTFGBG);
- wgtprintf (0, 0, NULL, "Making shade table...");
-
- wnormscreen ();
- for (i = 0; i <= numshades; i++)
- {
- wgtprintf (0, 8, NULL, "Color %03hi", i);
- wcreateshade (i, numshades, table, palette);
- }
-
- return table;
- }
-
-
-
-
- block wcreate_translucent_table (color *pal)
- /* Creates a translucent table */
- {
- float lightlevel1;
- float lightlevel2;
- float fr, fg, fb;
- float fr2, fg2, fb2;
- long ir, ig, ib;
-
- long absr, absg, absb;
-
- short col, col2;
- short findcol;
-
- unsigned long lowest;
- unsigned char bestfit;
- unsigned long coldif;
- unsigned char *table;
-
- table = (unsigned char *)malloc (65536);
-
- lightlevel1 = percent_foreground; /* Percent of color 1 (foreground) */
- lightlevel2 = percent_background; /* Percent of color 2 (background) */
-
- /* Lightlevel1 and lightlevel2 must total to 1 */
-
- /* Translucency is created by taking two colors, multiplying the
- RGB values by a percentage, and adding the RGB values together. The
- new color will contain a little bit of each oringal color. */
-
-
- /* For each of the 256 colors, we can mix with any other color, therefore
- we need a 256x256 table. */
-
- wtextcolor (128);
- wtexttransparent (TEXTFGBG);
- wgtprintf (0, 0, NULL, "Making translucency table... ");
-
- for (col2 = 0; col2 < 256; col2++)
- {
- for (col = 0; col < 256; col++)
- {
- fr = (float)pal[col].r * lightlevel1;
- fg = (float)pal[col].g * lightlevel1;
- fb = (float)pal[col].b * lightlevel1;
-
- fr2= (float)pal[col2].r * lightlevel2;
- fg2= (float)pal[col2].g * lightlevel2;
- fb2= (float)pal[col2].b * lightlevel2;
-
- ir = (fr + fr2);
- ig = (fg + fg2);
- ib = (fb + fb2);
-
- lowest = 655350;
- for (findcol = 0; findcol < 256; findcol++)
- {
- absr = abs ( (long)pal[findcol].r - ir) * 30;
- absg = abs ( (long)pal[findcol].g - ig) * 59;
- absb = abs ( (long)pal[findcol].b - ib) * 11;
-
- // coldif = sqrt(absr*absr + absg*absg + absb*absb);
- coldif = absr*absr + absg*absg + absb*absb;
- if (coldif < lowest)
- {
- lowest = coldif;
- bestfit = findcol;
- }
- }
- table[col2 * 256L + col] = bestfit;
- }
-
- wgtprintf (0, 8, NULL, "Color %03hi", col2);
- }
-
- return table;
- }
-
-
- long move_counter;
- long frame_counter;
-
- void movement_timer (void)
- {
- frame_counter++;
- }
-
-
- void wshadesource (block shadetable, block source, int length);
- #pragma aux wshadesource = \
- "push ebp" \
- "push ecx" \
- "cld" \
- "mov ebp, edx" \
- "mov ebx, 0" \
- "mov edi, esi" \
- "shr ecx, 1" \
- "cmp ecx, 0" \
- "je oneshadepixel"\
- "shadeloop: mov bl, [esi]" \
- "mov al, [ebp + ebx]" \
- "inc esi" \
- "mov bl, [esi]" \
- "mov ah, [ebp + ebx]" \
- "mov [edi], ax" \
- "add edi, 2" \
- "inc esi" \
- "dec ecx" \
- "jnz shadeloop" \
- "oneshadepixel: pop ecx" \
- "and ecx, 1" \
- "jz slinedone" \
- "mov bl, [esi]" \
- "mov al, [ebp + ebx]" \
- "mov [edi], al" \
- "slinedone: pop ebp" \
- parm [edx] [esi] [ecx] \
- modify exact [eax ebx ecx edx esi edi] nomemory;
-
-
- unsigned char shadesourcetable[256];
-
- void shade_screen (void)
- {
- wshadesource (shadesourcetable, virt+4, 64000L);
- }
-
-
- void wcreate_shadesource_table (color *palette)
- {
- float fr, fg, fb;
- long ir, ig, ib;
-
- long absr, absg, absb;
-
-
- int r,g,b;
-
- short col;
- short findcol;
-
- unsigned long lowest;
- unsigned char bestfit;
- unsigned long coldif;
-
- for (col = 0; col < 256; col++)
- {
-
- fr = (float)palette[col].r * (motion_blur_factor);
- fg = (float)palette[col].g * (motion_blur_factor);
- fb = (float)palette[col].b * (motion_blur_factor);
-
- ir = fr;
- ig = fg;
- ib = fb;
-
- lowest = 655350;
- for (findcol = 0; findcol < 256; findcol++)
- {
- absr = abs ( (long)palette[findcol].r - ir);
- absg = abs ( (long)palette[findcol].g - ig);
- absb = abs ( (long)palette[findcol].b - ib);
-
- coldif = absr + absg + absb;
- if ((coldif < lowest) && (findcol != col))
- {
- lowest = coldif;
- bestfit = findcol;
- }
- }
- shadesourcetable[col] = bestfit;
- }
-
- }
-
-
-
-
-
- void main(int argc, char *argv[])
- {
- short oldmode;
- int drawnum;
-
- short i;
-
- int vx, vy;
- int mx, my;
-
- float rx, ry, rz;
- float trx, try, trz;
-
- oldmode = wgetmode();
-
- if (argc == 1)
- {
- printf ("\n3D_CAM filename.3ds [vmode]\n\nWhere vmode is one of:\n");
- printf ("\n1 VESA 640x350x256");
- printf ("\n2 VESA 640x400x256");
- printf ("\n3 VESA 640x480x256");
- printf ("\n4 VESA 800x600x256");
- printf ("\n5 VESA 1024x768x256\n");
- exit (0);
- }
-
- printf ("Enter the rendering method: \n");
- printf ("0 = Wireframe\n");
- printf ("1 = Solid\n");
- printf ("2 = Gouraud Shaded\n");
- printf ("3 = Texture Mapped\n");
- printf ("4 = Flat Shaded Texture Mapped\n");
- printf ("5 = Gouraud Shaded Texture Mapped\n");
- printf ("6 = Translucent Texture Mapped\n");
- printf ("7 = Translucent Gouraud Shaded\n");
- printf ("8 = Gouraud with Phong Palette\n");
- printf ("9 = Gouraud Texture with Phong Palette\n");
- printf ("10 = Translucent Gouraud with Phong Palette\n");
-
- scanf ("%d", &rendermethod);
- if ((rendermethod < 0) || (rendermethod > 10))
- exit (0);
-
- printf ("Motion Blur? 0 = NO, 1 = YES\n");
- scanf ("%d", &motion_blur);
- if ((motion_blur < 0) || (motion_blur > 1))
- exit (0);
-
- if (motion_blur)
- {
- printf ("Fade Factor: (percentage of previous image)\n");
- scanf ("%f", &motion_blur_factor);
- }
-
- load_3ds (argv[1], vertices);
-
- for (i = 0; i < totalobjects; i++)
- {
- wset_object_color (i, 0);
-
- if (rendermethod == PHONG)
- wset_object_type (i, GOURAUD);
- else if (rendermethod == TRANSLUCENT_PHONG)
- wset_object_type (i, TRANSLUCENT_GOURAUD);
- else if (rendermethod == PHONG_TEXTURE)
- wset_object_type (i, GOURAUD_SHADED_TEXTURE);
- else
- wset_object_type (i, rendermethod);
- }
-
- printf ("\n\n\n\n\n\nTotal of: %8d points\n", worldpoints);
- printf ("Total of: %8d faces\n", totalpoly);
- printf ("Total of: %8d objects\n", totalobjects);
- printf ("Start obj 1 = %d\n", objectlist[0].start_poly);
- printf ("End obj 1 = %d\n", objectlist[0].end_poly);
-
- printf ("Memory free: %8d\n\n\n", getmemfree() );
- printf ("Keyboard Controls:\n");
- printf ("LEFT & RIGHT Dec/Inc X Camera position\n");
- printf (" UP & DOWN Dec/Inc Y Camera position\n");
- printf ("PGUP & PGDN Dec/Inc Z Camera position\n");
- printf ("PLUS & MINUS Inc/Dec Camera movement scale\n");
- printf ("CTRL & one of the above Rotate object\n");
- printf (" I & O Inc/Dec Texture Scale\n");
- printf (" ESC Quit\n");
- getch ();
-
- if ((rendermethod == TRANSLUCENT_GOURAUD) ||
- (rendermethod == TRANSLUCENT_PHONG) ||
- (rendermethod == TRANSLUCENT_TEXTURE))
- {
- translucent_table = load_table ("trans.dat", 65536L);
- if (translucent_table == NULL)
- {
- printf ("Translucent Factors\n");
- printf ("Percentage of foreground:\n");
- scanf ("%f", &percent_foreground);
- printf ("Percentage of background:\n");
- scanf ("%f", &percent_background);
- }
- }
-
-
- vga256 ();
-
- if ((argc == 3) && (atoi (argv[2]) < 6) && (atoi (argv[2]) > 0))
- wvesa_init (vmodes[atoi (argv[2]) - 1] );
- /* Enter SVGA mode */
-
- render_all = 0; /* Perform backface removal */
- set_initial_palette ();
- wsetpalette (0, 255, pal);
-
-
- if ((rendermethod == FLAT_SHADED_TEXTURE) ||
- (rendermethod == TEXTURE) ||
- (rendermethod == GOURAUD_SHADED_TEXTURE) ||
- (rendermethod == TRANSLUCENT_TEXTURE) ||
- (rendermethod == PHONG_TEXTURE))
- /* Using some kind of texture mapping */
- {
- textures[0] = wloadpcx ("texture.pcx", pal);
- wsetpalette (0, 255, pal);
- /* Load in the texture and set the palette */
-
-
- /* Make any shade tables needed */
- if ((rendermethod == FLAT_SHADED_TEXTURE) ||
- (rendermethod == GOURAUD_SHADED_TEXTURE))
- {
- shadetable = load_table ("shade.dat", (NUMSHADES + 1) * 256L);
- if (shadetable == NULL)
- {
- shadetable = wcreate_shade_table (NUMSHADES, pal);
- save_table ("shade.dat", shadetable, (NUMSHADES + 1) * 256L);
- }
- render_shadetable = shadetable;
- }
- else if (rendermethod == PHONG_TEXTURE)
- {
- shadetable = load_table ("phong.dat", (NUMSHADES + 1) * 256L);
- if (shadetable == NULL)
- {
- shadetable = wcreate_shade_table (NUMSHADES, pal);
- save_table ("phong.dat", shadetable, (NUMSHADES + 1) * 256L);
- }
- render_shadetable = shadetable;
- }
- }
-
- if ((rendermethod == TRANSLUCENT_GOURAUD) ||
- (rendermethod == TRANSLUCENT_PHONG) ||
- (rendermethod == TRANSLUCENT_TEXTURE))
- {
- if (translucent_table == NULL)
- {
- translucent_table = wcreate_translucent_table (pal);
- save_table ("trans.dat", translucent_table, 65536L);
- }
-
- render_all = 1;
- /* Render everything, since we will be able to see through the object */
-
- render_shadetable = translucent_table;
-
- }
-
-
-
- wclip (0, 0, WGT_SYS.xres - 1, WGT_SYS.yres - 1);
-
- winit_triangle_renderer (WGT_SYS.yres);
-
- virt = wnewblock (0, 0, WGT_SYS.xres - 1, WGT_SYS.yres - 1);
- render_shades = 64;
-
- if (rendermethod == GOURAUD)
- for (i = 0; i < totalobjects; i++)
- wset_object_color (i, 0);
-
-
- if ((rendermethod == PHONG) || (rendermethod == TRANSLUCENT_PHONG))
- {
- for (i = 0; i < totalobjects; i++)
- wset_object_color (i, 0);
- render_shades = 256;
- }
-
- if (rendermethod == WIREFRAME)
- {
- for (i = 0; i < totalobjects; i++)
- wset_object_color (i, 63);
- render_all = 1;
- }
-
-
- if (motion_blur)
- wcreate_shadesource_table (pal);
-
-
- wsetscreen (virt);
-
- installkbd ();
-
- winittimer();
- wstarttimer (movement_timer, TICKS(64));
-
- for (i = 0; i < totalobjects; i++)
- map_points (i, vertices, scale);
-
- /* Main loop */
- do
- {
- drawnum = 0;
-
- wset_light (camera_x, camera_y, camera_z);
- wset_camera (camera_x, camera_y, camera_z);
- wset_focus (focus_x, focus_y, focus_z);
- wset_view ();
-
- for (i = 0; i < totalobjects; i++)
- wworld_2_view (&objectlist[i], &drawnum, vertices);
-
- wsetscreen (virt);
-
- if (!motion_blur)
- wcls (0);
- else
- shade_screen ();
-
- draw_polys (vertices, drawnum);
-
- wtextcolor (255);
- wgtprintf (0, 0, NULL, "Polys: %d", drawnum);
-
- if (kbdon[0x3B]) /* F1 Load */
- load_ptext (totalpoly);
-
- if (kbdon[0x3D]) /* F3 Save */
- save_ptext (totalpoly);
-
- if (kbdon[29]) /* CTRL */
- {
- rx = ry = rz = 0;
-
- if (kbdon[72]) // up
- ry -= movectr;
- if (kbdon[80]) // down
- ry += movectr;
- if (kbdon[0x4b]) // left
- rx -= movectr;
- if (kbdon[0x4d]) // right
- rx += movectr;
- if (kbdon[73]) // PGUP
- rz -= movectr;
- if (kbdon[81]) // PGDN
- rz += movectr;
-
- if ((rx != 0) || (ry != 0) || (rz != 0))
- {
- for (i = 0; i < totalobjects; i++)
- rotate_object (&objectlist[i], vertices, rx, ry, rz, 0, 0, 0);
- }
- }
- else
- {
- if (kbdon[72]) /* up */
- camera_y -= movectr;
- if (kbdon[80]) /* down */
- camera_y += movectr;
- if (kbdon[0x4b]) /* left */
- camera_x -= movectr;
- if (kbdon[0x4d]) /* right */
- camera_x += movectr;
- if (kbdon[73]) /* PGUP */
- camera_z -= movectr;
- if (kbdon[81]) /* PGDN */
- camera_z += movectr;
- }
-
- wtextcolor (255);
- wtexttransparent (TEXTFGBG);
- if (kbdon[78]) /* PLUS key */
- {
- movectr = movectr + 0.3;
- wgtprintf (0, 0, NULL, "New movement amount for camera: %7.1f", movectr);
- }
-
- if (kbdon[74]) /* MINUS key */
- {
- movectr = movectr - 0.3;
- wgtprintf (0, 0, NULL, "New movement amount for camera: %7.1f", movectr);
- }
-
- if (kbdon[23]) /* I key */
- {
- scale += 0.1;
- for (i = 0; i < totalobjects; i++)
- map_points (i, vertices, scale);
- }
-
- if (kbdon[24]) /* O key */
- {
- scale -= 0.1;
- for (i = 0; i < totalobjects; i++)
- map_points (i, vertices, scale);
- }
-
-
-
- if (movectr < 0.3)
- movectr = 0.3;
-
- wnormscreen ();
- if (WGT_SYS.bankswitch != NULL)
- wvesa_putblock (0, 0, virt, NORMAL);
- else memcpy (abuf, virt+4, 64000);
- //wputblock (0, 0, virt, NORMAL);
-
- } while (!kbdon[1]); /* Until ESC is hit */
-
- wstoptimer ();
- wdonetimer ();
-
- wsetmode (oldmode);
-
- uninstallkbd ();
-
- wdeinit_triangle_renderer ();
-
- wfreeblock (virt);
-
- if ((rendermethod == FLAT_SHADED_TEXTURE) ||
- (rendermethod == GOURAUD_SHADED_TEXTURE) ||
- (rendermethod == PHONG_TEXTURE))
- free (shadetable);
- if ((rendermethod >= TEXTURE) && (rendermethod <= TRANSLUCENT_TEXTURE))
- wfreeblock (textures[0]);
- if ((rendermethod == TRANSLUCENT_TEXTURE) ||
- (rendermethod == TRANSLUCENT_GOURAUD) ||
- (rendermethod == TRANSLUCENT_PHONG))
- free (translucent_table);
- }
-
-
-
-